package game.leon.engine.net.example.server;

import game.leon.engine.net.GateMessageHandler;
import game.leon.engine.net.GateSession;
import game.leon.engine.net.codec.GateRawMessage;
import game.leon.engine.net.example.server.exception.MessageLoopStopException;
import game.leon.engine.utils.LinkedNode;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.locks.ReentrantLock;

/**
 * User: bianpeng
 * Date: 11-12-27
 * 异步消息处理
*/
@Component
public class ServerMessageReceiver implements GateMessageHandler {
    private Logger logger = Logger.getLogger(getClass());
    private ReentrantLock messageLock = new ReentrantLock();
    private LinkedNode<Message> messageList;
    @Autowired
    private ServerMessageConsumer serverMessageConsumer;
    @PostConstruct
    public void init() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    for(;;) {
                        if (messageList != null) {
                            LinkedNode<Message> node = null;
                            messageLock.lock();
                            try {
                                node = messageList;
                                messageList = null;
                            } finally {
                                messageLock.unlock();
                            }
                            serverMessageConsumer.execute(node);
                        } else {
                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                logger.debug("message loop wait failed");
                            }
                        }
                    }
                } catch (MessageLoopStopException ex) {
                    logger.info("message loop stoped " + ex.getMessage());
                }
            }
        }).start();
    }
    @Override
    public void execute(GateSession session, GateRawMessage message) {
        messageLock.lock();
        try {
            messageList = LinkedNode.cons(new Message(session, message), messageList);
        } finally {
            messageLock.unlock();
        }
    }
}
